////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Filename:    GreenLightGuts.h                                             //
//  Developer:   Tommy Riddle                                                 //
//  Create date: 04/13/2007                                                   //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Description: This is the class declaration for the slot gut of the        //
//               Australian Slot machine called Green Light.                  //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//        Copyright (c) 2007 - Realtime Gaming.  All rights reserved.         //
////////////////////////////////////////////////////////////////////////////////

#if !defined(__GREENLIGHTGUTS_H__)
#define __GREENLIGHTGUTS_H__

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


#include "slotguts.h"

class GreenLightGuts : public SlotGuts
{
public:
	GreenLightGuts();

	virtual ~GreenLightGuts();

private:
	// Shared enums between client and server
	#include "GreenLightCommon.h"

	// Probability Tables
    enum ProbabilityTables
    {
		PROB_TABLE_RACE_1_FINISHES,
		PROB_TABLE_RACE_2_FINISHES,
		PROB_TABLE_GREEN_LIGHTS_FROM_2_WHITES_BASE,
		PROB_TABLE_GREEN_LIGHTS_FROM_3_WHITES_BASE,
		PROB_TABLE_GREEN_LIGHTS_FROM_4_WHITES_BASE,
		PROB_TABLE_GREEN_LIGHTS_FROM_5_WHITES_BASE,
		PROB_TABLE_GREEN_LIGHTS_FROM_2_WHITES_FREE,
		PROB_TABLE_GREEN_LIGHTS_FROM_3_WHITES_FREE,
		PROB_TABLE_GREEN_LIGHTS_FROM_4_WHITES_FREE,
		PROB_TABLE_GREEN_LIGHTS_FROM_5_WHITES_FREE,
	};

	// Helpful lookup arrays.
	static SpinResult m_aLineWinSpinResults[][6];

	static SpinResult m_aGreenLightSpinResults[6];
	static SpinResult m_aWhiteLightSpinResults[6];

	// Inline functions to use with the arrays that also do
	// bounds checking.
	static SpinResult lookupLineWinSpinResult( uint8 nIconType, uint8 nCount )
	{
		if ( nIconType < NUM_VALID_ICONS && nCount < 6 )
		{
			return m_aLineWinSpinResults[ nIconType ][ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	static SpinResult lookupGreenLightSpinResult( uint8 nCount )
	{
		if ( nCount < 6 )
		{
			return m_aGreenLightSpinResults[ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	static SpinResult lookupWhiteLightSpinResult( uint8 nCount )
	{
		if ( nCount < 6 )
		{
			return m_aWhiteLightSpinResults[ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	// Helper functions for classifyStops.
	SpinResult getDriverLineWinResult( uint8* stops ) const;

	SpinResult getLineWinResultWithPossibleSubstitution(
		uint8* stops, uint8 line, uint8 testIcon, bool& bSubstitution );

	bool doesDriverLineWinPayMore( SpinResult srDriver, SpinResult srOther,
		bool bSubstitution ) const;

	// Helper functions for classifyScatters.
	void tryForJackpot( SlotSpin* spin );

	SpinResult getWhiteLightResult( SlotSpin* spin, int32& nNumWhiteLightIcons, int32& nWhiteLightPositions ) const;
	SpinResult getGreenLightResult( SlotSpin* spin, int32 nNumWhiteLightIcons, int32 nWhiteLightPositions, int32& nNumGreenLightIcons, int32& nGreenLightPositions ) const;
	
	void addWhiteLightScatter( SlotSpin* spin, SpinResult srWhiteLightResult, int32 nWhiteLightPositions );
	void addGreenLightScatter( SlotSpin* spin, SpinResult srGreenLightResult, int32 nGreenLightPositions );
	void addFeatureTriggerScatter( SlotSpin* spin, int32 nNumGreenLightIcons, int32 nGreenLightPositions );

	static int32 calculateRaceResultIndex( int32 nRace, uint8 nCar )
	{
		// Make sure the race is valid.
		ASSERT( nRace == 1 || nRace == 2 );

		// Make sure the car is valid.
		ASSERT( nCar >= RF_CAR_1 && nCar < NUM_RACE_CAR_CHOICES );

		// Calculate the proper index to use.
		int32 nIndex = ( ( nRace - 1 ) * NUM_RACE_CAR_CHOICES ) + nCar;

		// Now return the proper subgame data index.
		return SGDIDX_RACE_RESULT + nIndex;
	}

	uint8 getRaceResult( uint8 nRace, uint8 nCar );
	void setRaceResult( uint8 nRace, uint8 nCar, uint8 nResult );
	uint8 determineRaceResults( RaceCarConstants ePlayerCar );

	uint8 getCurrentRace();
	void setCurrentRace( uint8 nRace );

	RaceCarConstants getPlayerCar();
	void setPlayerCar( RaceCarConstants nPlayerCar );

	void addFreeSpinsBonus( uint8 nResult );
	void addMultiplierBonus( uint8 nResult );

public:
	virtual void classifyStops( SpinLine* spinline, uint8* stops, uint8 bet, uint8 line,
		uint8& rtnresult, uint8& multiplier );

	virtual void classifyScatters( SlotSpin *spin );

    virtual bool8 isValidGuts();

    virtual void getGameModeMultiplierAndNoteId( uint8& nGameModeMultiplier, uint8& nNoteId );

	virtual bool8 processClientData( uint8 bonusGameType, int32 bonusDataCount, int32 *bonusData );

protected:
	// Override these framework functions.
	virtual bool8 hasSavedGames();

	virtual void Debug_SetLoserStops( uint8* pStops );
};


#endif // !defined(__GREENLIGHTGUTS_H__)
